home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / dviware / dvi2ps / dvi-to-ps / findfile.c < prev    next >
C/C++ Source or Header  |  1990-10-01  |  10KB  |  318 lines

  1. /* findfile.c */
  2. /* Copyright 1985 Massachusetts Institute of Technology */
  3. /* modified by Peter Damron 1987 University of Washington */
  4. /*---------------------------------------------------------------------*/
  5. #ifndef lint
  6. static char rcsid[] = "$Header: findfile.c,v 2.0 88/06/07 15:02:38 peterd Rel2 $";
  7. #endif lint
  8. /*---------------------------------------------------------------------*/
  9.  
  10. #include <stdio.h>
  11. #include <strings.h>
  12. #include <sys/types.h>
  13. #include <sys/file.h>
  14. #include <sys/dir.h>
  15. #include "findfile.h"
  16.  
  17. #ifndef TRUE
  18. #define TRUE -1
  19. #define FALSE 0
  20. #endif TRUE
  21.  
  22. /* normally defined in <sys/dir.h>, but just to make sure */
  23. #ifndef MAXNAMLEN
  24. #define MAXNAMLEN 255
  25. #endif MAXNAMLEN
  26.  
  27. /*---------------------------------------------------------------------*/
  28. /* find a font file in a single directory */
  29. /* true if it found the font file, false otherwise */
  30. /* s is the return filename string, if found (e.g. area/stylepoint.maggf */
  31. /* area is directory to look in */
  32. /* style is the font style (e.g. cmr) */
  33. /* point is the design point size of the font */
  34. /* mag is the magnification - adjusted for this dpi and font format */
  35.  
  36. int
  37. FindFileInDir(area, style, point, mag, s)
  38.     char *area,*style,*s;
  39.     int point,mag;
  40. {
  41.     FILE *f;
  42.     char buf[MAXNAMLEN];
  43.     int found = 0;
  44.  
  45.     /* presence of file "SUBDIR" means subdirectory per font style */
  46.     sprintf(s,"%s/SUBDIR",area);
  47.  
  48. #ifdef USEPXL
  49.     if (!access(s,F_OK)) {
  50.     sprintf(s,"%s/%s/%s%d.%dpxl",area,style,style,point,mag);
  51.     } else {
  52.     sprintf(s,"%s/%s%d.%dpxl",area,style,point,mag);
  53.     }
  54. #else not USEPXL
  55.     if (!access(s,F_OK)) {
  56.     sprintf(s,"%s/%s/%s%d.%dgf",area,style,style,point,mag);
  57.     } else {
  58.     sprintf(s,"%s/%s%d.%dgf",area,style,point,mag);
  59.     }
  60. #endif USEPXL
  61.  
  62.     if (!access(s,R_OK)) {
  63.     /* font file is there and we can read it */
  64.     return(TRUE);
  65.     }
  66.  
  67.     /* font file is not there */
  68.     /* try to write out a message to "NEEDED" file */
  69.     sprintf(buf,"%s/NEEDED",area);
  70.     if (!access(buf,W_OK)) {
  71. #ifdef USEPXL
  72.     sprintf(s,"%s%d.%dpxl\n",style,point,mag);
  73. #else not USEPXL
  74.     sprintf(s,"%s%d.%dgf\n",style,point,mag);
  75. #endif USEPXL
  76.     f = fopen(buf,"r+");
  77.     while (fgets(buf,sizeof(buf),f)) {
  78.         if (!strcmp(buf,s)) {
  79.         found++;
  80.         }
  81.     }
  82.     if (!found) fputs(s,f);
  83.     fclose(f);
  84.     }
  85.     return(FALSE);
  86. }
  87.  
  88. /*---------------------------------------------------------------------*/
  89. /* find a font file in a directory vector (path) */
  90. /* true if it found a font file, false otherwise */
  91. /* s is the return filename string, if found (e.g. area/stylepoint.maggf */
  92. /* dirvec is a vector of directory strings */
  93. /* dirveclen is the length of dirvec vector */
  94. /* area is the first directory to search */
  95. /* name is the font style and font design size concatenated */
  96. /* mag is the magnification spec - modified for dpi and font format */
  97. /* s is the return filename string */
  98. /* nname is the return name if a substitution is made */
  99. /* nmag is the return magnification if a substitution is made */
  100.  
  101. int FindFontFile(dirvec,dirveclen,name, mag, s, nname, nmag)
  102.     char *dirvec[],*name,*s,*nname;
  103.     int dirveclen,mag,*nmag;
  104. {
  105.     int i,point;
  106.     char style[MAXNAMLEN];
  107.  
  108.     /* default is to use the input name and mag as the output name and mag */
  109.     strcpy(nname,name);
  110.     *nmag = mag;
  111.  
  112.     /* break the font name into style and design point size */
  113.     point = -1;
  114.     (void) sscanf(name,"%[^0123456789.]%d",style,&point);
  115.  
  116. #ifdef NOTDEF
  117.     /* should check these values here */
  118.     Warning("internal - find font %s style %s point %d mag %d\n",
  119.         name,style,point,mag);
  120. #endif NOTDEF
  121.  
  122.     /* First check dir area given in DVI file */
  123.     /* Then check along dirvec */
  124.     for (i = 0; i < dirveclen; i++)  {
  125.     if (FindFileInDir(dirvec[i], style, point, mag, s)) {
  126.         return(TRUE);
  127.     }
  128.     }
  129.  
  130.     /* next check for closest magnification along dirvec */
  131.     /* note: no check in area here */
  132.     return(FindAnyFile(dirvec,dirveclen,style,point,mag,name,s,nname,nmag));
  133. }
  134.  
  135. /*---------------------------------------------------------------------*/
  136. /* find out how similar two strings are */
  137. /* used to compare font style names */
  138. /* rather an arbitrary measure */
  139. /* e.g. may not have anything to do with how similar two fonts are */
  140.  
  141. int StrDiff(s1,s2)
  142.     char *s1,*s2;
  143. {
  144.     register int diff = 0;
  145.  
  146.     while (*s1 && *s2) diff += abs(*s1++ - *s2++);
  147.     while (*s1) diff += *s1++;
  148.     while (*s2) diff += *s2++;
  149.     return(diff);
  150. }
  151.  
  152. /*---------------------------------------------------------------------*/
  153. /* scan a single directory for the best font file */
  154.  
  155. ScanDir(dir,
  156.      style,point,mag,
  157.      beststyle,bestname,bestpoint,bestmag,
  158.      min_ds,min_dpm,min_dp)
  159.     char *dir,*style,*beststyle,*bestname;
  160.     int point,mag,*bestpoint,*bestmag,*min_ds,*min_dpm,*min_dp;
  161. {
  162.     DIR *dirstream;        /* stream of file records in this dir */
  163.     register struct direct *dirrecord;    /* pointer to a file record */
  164.     char qstyle[MAXNAMLEN];    /* style name of current file */
  165.     int qpoint;            /* point size of current file */
  166.     int qmag;            /* mag size of current file */
  167.     register int ds;            /* local delta in style */
  168.     register int dpm;            /* local delta in point*mag */
  169.     register int dp;            /* local delta in point */
  170.  
  171.     /* go through the files in this directory */
  172.     if (dirstream = opendir(dir)) {
  173.     while (dirrecord = readdir(dirstream)) {
  174. #ifdef USEPXL
  175.         /* only use *pxl files */
  176.         if (!strcmp(dirrecord->d_name+dirrecord->d_namlen-3,"pxl")) {
  177. #else not USEPXL
  178.         /* only use *gf files */
  179.         if (!strcmp(dirrecord->d_name+dirrecord->d_namlen-2,"gf")) {
  180. #endif USEPXL
  181.         /* parse the filename into style, point, mag */
  182.         qpoint = -1; qmag = -1;
  183.         (void) sscanf(dirrecord->d_name,"%[^0123456789.]%d.%d",
  184.                   qstyle,&qpoint,&qmag);
  185.         /* compute differences */
  186.         ds = StrDiff(style,qstyle);
  187.         dpm = abs((point*mag) - (qpoint*qmag));
  188.         dp = abs(point - qpoint);
  189. #ifdef NOTDEF
  190.         dm = abs(mag - qmag);
  191. #endif NOTDEF
  192.         /* check for a better font than before */
  193.         if ((ds < *min_ds)
  194.             || (ds == *min_ds && dpm <= *min_dpm)
  195.             || (ds == *min_ds && dpm == *min_dpm && dp <= *min_dp)) {
  196.             sprintf(bestname,"%s/%s",dir,dirrecord->d_name);
  197.             strcpy(beststyle,qstyle);
  198.             *bestpoint = qpoint;
  199.             *bestmag = qmag;
  200.             *min_ds = ds;
  201.             *min_dpm = dpm;
  202.             *min_dp = dp;
  203.         }
  204.         }
  205.     }
  206.     closedir(dirstream);
  207.     }
  208. }
  209.  
  210. /*---------------------------------------------------------------------*/
  211. /* scan a font sub-directory tree for the best font file */
  212.  
  213. ScanTree(dir,name,
  214.     style,point,mag,
  215.     beststyle,bestname,bestpoint,bestmag,
  216.     min_ds,min_dpm,min_dp)
  217.     char *dir,*name,*style,*beststyle,*bestname;
  218.     int point,mag,*bestpoint,*bestmag,*min_ds,*min_dpm,*min_dp;
  219. {
  220.     DIR *dirstream;
  221.     struct direct *dirrecord;
  222.     int ds;
  223.     char pdir[MAXNAMLEN];
  224.  
  225.     if (dirstream = opendir(dir)) {
  226.     while (dirrecord = readdir(dirstream)) {
  227.         if (dirrecord->d_name[0] != '.') {
  228.         ds = StrDiff(name,dirrecord->d_name);
  229.         if (ds <= *min_ds) {
  230.             sprintf(pdir,"%s/%s",dir,dirrecord->d_name);
  231.             /* try this sub-directory */
  232.             ScanDir(pdir,
  233.                 style,point,mag,
  234.                 beststyle,bestname,bestpoint,bestmag,
  235.                 min_ds,min_dpm,min_dp);
  236.             /* we should update min_ds at this point */
  237.             /* but we rely on ScanDir to do that */
  238.         }
  239.         }
  240.     }
  241.     closedir(dirstream);
  242.     }
  243. }
  244.  
  245. /*---------------------------------------------------------------------*/
  246. /* finds the best match to the desired font */
  247. /* searches through directory vector (path) */
  248. /* best in what sense ??? */
  249.  
  250. int FindAnyFile(dirvec,dirveclen,style,point,mag,name,s,nname,nmag)
  251.     char *dirvec[],*style,*name,*s,*nname;
  252.     int dirveclen,point,mag,*nmag;
  253. {
  254.     char foo[MAXNAMLEN];    /* temp file name string */
  255.     char bestname[MAXNAMLEN];    /* best font file name string */
  256.     char beststyle[MAXNAMLEN];    /* best font style name string */
  257.     int i;        /* temp index into directory vector */
  258.     int bestpoint;    /* best font point size */
  259.     int bestmag;    /* best font magnification size */
  260.     int min_ds;        /* minimum delta found in font sytle name string */
  261.     int min_dpm;    /* minimum delta found in font point*mag */
  262.     int min_dp;        /* minimum delta found in font point */
  263.     
  264.     bestname[0] = '\0'; 
  265.     min_ds = min_dpm = min_dp = 9999999;
  266.     for (i = 0; i < dirveclen; i++) {
  267.     /* check for font sub-directory tree (not flat) */
  268.     sprintf(foo,"%s/SUBDIR",dirvec[i]);
  269.     if (!access(foo,F_OK)) {
  270.         ScanTree(dirvec[i],name,
  271.             style,point,mag,
  272.             beststyle,bestname,&bestpoint,&bestmag,
  273.             &min_ds,&min_dpm,&min_dp);
  274.     } else {
  275.         ScanDir(dirvec[i],
  276.             style,point,mag,
  277.             beststyle,bestname,&bestpoint,&bestmag,
  278.             &min_ds,&min_dpm,&min_dp);
  279.     }
  280.     }
  281.     if (bestname[0]) {
  282.     /* well we found something that looks ok */
  283.     /* get return values: s, nname, nmag */
  284.     if (bestpoint > 0) {
  285.         sprintf(nname,"%s%d",beststyle,bestpoint);
  286.     } else {
  287.         /* does this ever get used? this looks bad */
  288.         strcpy(nname,beststyle);
  289.     }
  290.     *nmag = bestmag;
  291.     strcpy(s,bestname);
  292.     /* issue a warning if we are doing a substitution */
  293.     if ((strcmp(beststyle,style)
  294.         || bestpoint != point || abs(bestmag - mag) > 2)) {
  295. #ifdef NOTDEF
  296.         Warning("Substituted font %s at mag %d for %s at mag %d\n",
  297.               nname,(bestmag * 4 + 3) / 6,
  298.               name,(mag * 4 + 3) / 6);
  299.               /* is this message very useful? */
  300.               /* why the magic numbers? */
  301.         /* this message could be better */
  302.         Warning("Substituted font %s at mag %d for %s at mag %d\n",
  303.               nname,bestmag,name,mag);
  304. #endif NOTDEF
  305. #ifdef USEPXL
  306.         Warning("Substituted font %s%d.%dpxl -> %s\n",style,point,mag,s);
  307. #else not USEPXL
  308.         Warning("Substituted font %s%d.%dgf -> %s\n",style,point,mag,s);
  309. #endif USEPXL
  310.     }
  311.     return(TRUE);
  312.     }
  313.     return(FALSE);
  314. }
  315.  
  316. /*---------------------------------------------------------------------*/
  317.  
  318.